home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
081-090
/
amok81
/
m2
/
demos
/
txt
/
features.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
7KB
|
252 lines
(*
* August 1992/bp/AMSoft
* Dieses Modul ist wenig sinnvoll, es soll lediglich viele der
* Möglichkeiten des M2Amiga-Systems aufzeigen.
*
* In der Demo-Version sind Register- und externe Variablen nicht erlaubt!
*
*)
MODULE Features;
(*
* Compileroptionen können an jedem Ort abgefragt, aber einige nur
* an bestimmten Orten verändert werden.
* Vordefinierte Namen aller Compileroptionen:
* Die Buchstaben und Ziffern in Klammern bezeichnen die Angabe
* der entsprechenden Option von der Kommandozeile.
* CaseChk (c)
* ChipBSS
* ChipCODE
* ChipDATA
* CopyDyn
* CStrings
* EntryExitCode
* Implementation
* Joker (j)
* LargeVars (y) (-y => residente Programme!)
* LoadA4
* LongAlign (l)
* m68010 (1)
* m68020 (2)
* m68030 (3)
* m68040 (4)
* m68881 (8)
* NameChk
* NilChk (n)
* OverflowChk (v)
* ParDealloc
* RangeChk (r)
* ReturnChk (f)
* SaveA4
* SaveAllRegs
* StackChk (s)
* StackParms (z)
* Volatile (h)
* (d) => -d heißt: Code optimieren und kein .ref-File erzeugen
*)
(*
* Dies ist eine Compiler-Anweisung. Compiler-Anweisungen beginnen
* mit (,* und $. Diese Anweisung löscht die Option LargeVars,
* woraufhin dieses Modul im SMALL-Data-Modell kompiliert wird.
*)
(*$ LargeVars:=FALSE *)
(*
* Die nachfolgende Compiler-Anweisung deklariert eine
* benutzerdefinierte Option und belegt sie mit dem Wert FALSE.
* Wenn der Bediener von der Kommandozeile "+oEnglish" eingibt,
* erhält die Option den Wert TRUE.
*)
(*$ DEFINE English:=FALSE *)
FROM SYSTEM IMPORT ADR,ASSEMBLE,CAST,TAG;
FROM DosD IMPORT FileInfoBlock;
IMPORT
Arts,
R,
IL:IntuitionL,
ID:IntuitionD;
CONST
(*
* Wir deklarieren nun eine Konstante, die abhängig von der Option
* "English" unterschiedliche Werte erhält.
* Nebenbei geben wir noch einmal ausdrücklich auf dem Bildschirm
* aus, welche Version wir gerade erstellen.
*)
(*$ IF English "Dies wird eine englische Version!\n\n" *)
message="No Window!";
(*$ ELSE "Deutsche Version!\n\n" *)
message="Kein Fenster!";
(*$ ENDIF *)
VAR
(*
* Die nachfolgende Variable wird auf einer Langwortgrenze
* abgelegt, die dos.library wird es uns danken:
*)
(*$ LongAlign:=TRUE *)
info: FileInfoBlock;
(*
* Die nächsten Variablen werden entweder auf Wort- oder auf
* Langwortgrenzen abgelegt. Dies hängt davon ab, welche Optionen
* der Bediener von der Kommandozeile angab.
*)
(*$ POP LongAlign *) (* alten Wert wiederherstellen *)
i,j:INTEGER;
(*
* Die folgenden Variablen und Prozeduren sind extern, d.h. mit
* einem fremden Assembler oder Compiler erstellt.
* Die erste Variable muß in einem Hunk mit den Namen __MERGED
* liegen und wird als SMALL-Variable deklariert.
* Die zweite Variable "chipImage" wird als LARGE-Variable
* deklariert und somit absolut adressiert. Da wir später nur
* ihre Adresse benötigen, deklarieren wir sie einfach als INTEGER.
* Da die Symbole einen Unterstrich enthalten, werden sie vom
* Linker in der Datei "FDemo.obj" gesucht, andernfalls müßten
* wir ihm den Dateinamen angeben.
*)
myMenu[<"FDemo_Menu"]: ID.Menu;
chipImage["FDemo_Image"]: INTEGER;
PROCEDURE Extern(VAR i: INTEGER; j:LONGINT):LONGINT; "FDemo_Proc";
(*
* Die folgende Prozedur demonstriert den Gebrauch von Register-
* Variablen und -Parametern. Zwei INTEGER-Variablen werden
* vertauscht. Die Parameter legen wir in Adressregister, weil
* sie VAR-Parameter sind, die aufrufende Prozedur also ihre Adressen
* übergibt. Der generierte Code steht in den Kommentaren.
*)
PROCEDURE Swap(VAR a{R.A0},b{R.A1}:INTEGER);
VAR help{R.D0}:INTEGER;
BEGIN
help:=a; (* MOVE.W (A0),D0 *)
a:=b; (* MOVE.W (A1),(A0) *)
b:=help; (* MOVE.W D0,(A1) *)
END Swap; (* RTS *)
(*
* Diese Prozedur demonstriert die Benutzung des Assemblers und der
* bedingten Kompilierung. Sie multipliziert zwei Zahlen und liefert
* den Betrag des Ergebnisses zurück. Das Gleiche würde natürlich durch
* den Ausdruck ABS(a*b) erreicht! Wir sehen hieran auch, daß die
* bedingte Kompilierung verschachtelt sein darf, und daß jede Option
* abgefragt werden kann.
* Da wir sie komplett in Assembler implementieren, darf der Compiler
* keinen Ein- und Ausgangscode generieren, was wir durch eine
* Compiler-Anweisung verhindern.
* Die Prozedur ist mit bedingter Kompilierung künstlich überladen,
* um einige Möglichkeiten aufzuzeigen. Man sollte sie GENAU ansehen!
*)
(*$ EntryExitCode:=FALSE *)
PROCEDURE MulAbs(z1,z2:LONGINT):LONGINT;
BEGIN
ASSEMBLE(
(*$ IF NOT EntryExitCode *) (* Ist zwar hier sicher AUS, aber
* vielleicht ändern wir es später? *)
LINK A5,#0 (* Im Grunde unnötig, erleichtert aber
* die Adressierung der Parameter *)
(*$ ENDIF *)
(*$ IF m68020 *) (* Wird dies Modul für die 68020 oder höhere
* kompiliert, dürfen wir MULS.L benutzen? *)
MOVE.L z1(A5),D0
MULS.L z2(A5),D0
(*$ IF OverflowChk *) (* Soll eine Überlaufprüfung erfolgen? *)
TRAPVS
(*$ ENDIF *)
(*$ ELSE *) (* Nicht 68020ff, wir brauchen Arts! *)
MOVE.L z1(A5),D0
MOVE.L z2(A5),D1
JSR Arts.Muls32(PC)
(*$ IF OverflowChk *) (* Soll eine Überlaufprüfung erfolgen? *)
TRAPV
(*$ ENDIF *)
(*$ ENDIF *)
TST.L D0 (* Die Flags sind zwar schon gesetzt, aber *)
BPL.S IsPos (* wir wollen doch auch noch ein Label zeigen *)
NEG.L D0
IsPos:
(*$ IF NOT EntryExitCode *)
UNLK A5
(*$ ENDIF *)
(*$ IF m68010 AND NOT EntryExitCode *) (* Wir müssen die Parameter
* selbst abbauen, dürfen
* wir RTD benutzen? *)
RTD #4 (* Wir haben 2 INTEGER, also 4 Byte *)
(*$ ELSIF NOT EntryExitCode *) (* Nein, 68000! *)
MOVE.L (A7)+,A0
ADDQ.L #4,A7
JMP (A0)
(*$ ENDIF *)
END);
END MulAbs;
(*
* Eine typisierte Konstante:
*)
TYPE
MyArr8 = ARRAY [0..7] OF INTEGER;
CONST
mix = MyArr8{ -10, 5, 9, 0, 0, 4, 3, 1};
alleEins = MyArr8{ 1, ..};
(*
* Nun kommt eine initialisierte Variable:
*)
VAR
myNewWin:=ID.NewWindow{
leftEdge: 150, topEdge: 90,
width:200, height: 80,
detailPen: 0, blockPen: 1,
idcmpFlags: ID.IDCMPFlagSet{},
flags: ID.WindowFlagSet{ID.windowDrag,ID.windowDepth,
ID.windowSizing,ID.activate},
title: ADR("Mein altes Fenster"),
screen: NIL,
(* alle anderen Elemente sind 0 *)
type:ID.ScreenFlagSet{ID.wbenchScreen}
};
tagBuffer: ARRAY [0..14] OF LONGINT;
myWin: ID.WindowPtr;
(*
* Im Hauptprogramm öffnen wir ein Window und warten ein Weilchen
* Falls das Fenster nicht geöffnet werden konnte, bringt das Modul
* Arts in einem Requester die Fehlermeldung auf den Schirm.
*)
BEGIN (* Hauptprogramm *)
IF Arts.kickVersion>=37 THEN (* haben wir Kickstart 2.0? *)
myWin:=IL.OpenWindowTagList(NIL,TAG(tagBuffer,
ID.waLeft, 150,
ID.waTop, 90,
ID.waWidth, 200,
ID.waHeight, 90,
ID.waIDCMP, 0,
ID.waFlags, ID.WindowFlagSet{ID.windowDrag,ID.windowDepth,
ID.windowSizing,ID.activate},
ID.waTitle, ADR("Mein neues Fenster"),
0));
ELSE
myWin:=IL.OpenWindow(myNewWin);
END;
Arts.Assert(myWin <> NIL, ADR(message));
Arts.BreakPoint(ADR("Absichtliche Unterbrechung"));
(*
* Der folgende Code wird am Programmende ausgeführt. Hier wird das
* Fenster geschlossen, wenn es noch geöffnet ist.
*)
CLOSE
IF myWin#NIL THEN
IL.CloseWindow(myWin);
myWin:=NIL
END;
END Features.